package models;

import java.util.*;

import javax.persistence.*;

import play.data.validation.*;
import play.db.jpa.*;

@Entity
public class User extends Model
{
	@Email
	@Required
	@Column(unique = true)
	public String					username;

	@Required
	@MinSize(8)
	public String					password;

	public boolean					isAdmin;

	@OneToMany(mappedBy = "user", cascade = CascadeType.ALL)
	public List<AbstractProfile>	abstractProfileList;

	/**
	 * Constructor of the Model : User
	 * 
	 * @author Rania Said
	 * @param username
	 *            : String username of the new user
	 * @param password
	 *            : String password of the new user
	 * @param fullname
	 *            : String full name of the new user
	 * @param isAdmin
	 *            : boolean which is true if the new user is an administrator
	 *            and false otherwise
	 */
	public User(String username, String password, String fullname,
			boolean isAdmin)
	{
		super();
		this.username = username;
		this.password = password;
		this.isAdmin = isAdmin;
	}

	/**
	 * This method is called upon authentication on user login.
	 * 
	 * @author Rania Said
	 * @param username
	 *            : String username of the user
	 * @param password
	 *            : String password of the user
	 * @return true if there is a match and false otherwise
	 */
	public static boolean connect(String username, String password)
	{
		User temp = find("byUsernameAndPassword", username, password).first();
		if (temp != null)
		{
			return true;
		}
		else
		{
			return false;
		}
	}

	/**
	 * This method returns a toString of the user.
	 * 
	 * @author Rania Said
	 * @return String containing info of the user
	 */
	@Override
	public String toString()
	{
		return "Username: " + username;
	}

	/**
	 * This method finds a User by username as search query
	 * 
	 * @author Rania Said
	 * @param username
	 *            : String username as a search query
	 * @return the User with a matching username if found or null otherwise
	 */
	public static User findByUsername(String username)
	{
		List<User> allUsers = User.findAll();
		for (int i = 0; i < allUsers.size(); i++)
		{
			User temp = (User) allUsers.get(i);
			if (temp.username.equalsIgnoreCase(username))
			{
				return temp;
			}
		}
		return null;
	}

	/**
	 * Redundancy Check: This method checks if the user is trying to insert a
	 * social profile in the same abstract profile that already contains this
	 * social profile, which would cause a redundancy problem
	 * 
	 * @author Rania Said
	 * @param inputAbstractProfile
	 *            : Abstract profile that the user wants to insert into
	 * @param uID
	 *            : long the uID of the user
	 * @return true if there is a redundancy problem and false otherwise
	 */
	public boolean checkInsertionSame(AbstractProfile inputAbstractProfile,
			long uID)
	{
		SocialProfile tempSocialProfile = SocialProfile.findByUID(uID);
		AbstractProfile tempAbstractProfile = tempSocialProfile.abstractProfile;

		if (tempAbstractProfile.equals(inputAbstractProfile))
		{
			return true;
		}
		else
		{
			return false;
		}
	}

	/**
	 * Linkability Check: This method checks if the user is trying to insert the
	 * same social profile in the another abstract profile which would cause a
	 * linkability problem
	 * 
	 * @author Rania Said
	 * @param uID
	 *            : long user ID of the user
	 * @return the abstract profile containing this social profile
	 */
	public AbstractProfile checkInsertionAnother(long uID)
	{
		SocialProfile tempSocialProfile = SocialProfile.findByUID(uID);
		AbstractProfile tempAbstractProfile = tempSocialProfile.abstractProfile;
		User tempUser = tempAbstractProfile.user;
		List<AbstractProfile> allAbstractProfiles = tempUser.abstractProfileList;

		for (int i = 0; i < allAbstractProfiles.size(); i++)
		{
			if (tempAbstractProfile.equals(allAbstractProfiles.get(i)))
			{
				return tempAbstractProfile;
			}
		}
		return null;
	}
}